const fs = require("fs");
const path = require("path");
const readline = require("readline");
const _ = require("koa-route");
const Koa = require("koa");
const { koaBody } = require("koa-body");
const app = new Koa();
const game = createGame();
const ip = require("koa-ip");
const gameSDK = require("../build/Release/game.node");
const { indexPort } = require("./config");
// app.use(ip(["::1", "172.31.18.95"])); // whitelist
app.use(koaBody());

app.use(
  _.post("/play", (ctx) => {
    ctx.body = game.update(ctx.request.body);
  })
);
app.use(
  _.post("/start", (ctx) => {
    game.start(ctx.request.body);
  })
);
app.use(
  _.post("/end", (ctx) => {
    game.end();
  })
);

app.use((ctx) => {});

function createGame() {
  let gameId = "";
  const maps = [];
  readline.emitKeypressEvents(process.stdin);
  process.stdin.setRawMode(true);
  process.stdin.on("keypress", (str, key) => {
    if (key.ctrl && key.name === "c") {
      end();
      process.exit(0);
    }
  });
  function end() {
    const html = fs.readFileSync("./render/template.html", "utf-8");
    const fileName = `./dist/game_${gameId}.html`;
    const dir = path.dirname(fileName);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    fs.writeFileSync(
      fileName,
      html.replace("$mockData$", JSON.stringify(maps))
    );
  }
  return {
    update(data) {
      let dataStr = JSON.stringify(data);
      if (data.battleId) {
        data.map = data.map.map((row) =>
          row.map((cell) => {
            switch (cell) {
              case "G":
                return 0;
              case "T":
                return 0;
              case "B":
                return 1;
              case "I":
                return 2;
              case "W":
                return 3;
              default:
                return -1;
            }
          })
        );
        data.propVoList.map((prop) => {
          prop.x = prop.x / 5;
          prop.y = prop.y / 5;
        });
        data.bulletSateVoList.map((bullet) => {
          bullet.x = bullet.x / 5;
          bullet.y = bullet.y / 5;
        });
        data.tankSatesVoList.map((tank) => {
          tank.x = tank.x / 5;
          tank.y = tank.y / 5;
        });
        data.safeAreaStateVo.x = data.safeAreaStateVo.x / 5;
        data.safeAreaStateVo.y = data.safeAreaStateVo.y / 5;
        data.safeAreaStateVo.r = data.safeAreaStateVo.r / 5;
        if (data.battleId !== gameId) {
          //new game
          maps.length = 0;
        }
        gameId = data.battleId;
        try {
          const dataCopy = JSON.stringify(data);
          const response = gameSDK.calculate(dataCopy);
          maps.push({
            request: JSON.parse(dataStr),
            response,
          });
          return response;
        } catch (error) {
          fs.writeFileSync("./errorData.json", dataStr);
          console.error(error);
        }
      }
      return {
        moveType: "STOP",
        shoot: false,
      };
    },
    start(data) {},
    end,
  };
}
app.listen(indexPort);
console.log("服务已启动：", "http://localhost:" + indexPort);
